package com.cardbaobao.cardbabyclient.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class BitmapUtil {
    static final int COMPRESS_QUALITY=80;//图片压缩质量，最多压缩20%
    /**
     * 根据图片路径获取压缩后的Bitmap
     *
     * @param imgPath   图片路径
     * @param reqWidth  期望压缩宽度
     * @param reqHeight 期望压缩高度
     * @return Bitmap对象
     */
    public static Bitmap getSmallBitmap(String imgPath, int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;// 如果该值设为true那么将不返回实际的bitmap对象，不给其分配内存空间但是可以得到一些解码边界信息即图片大小等信息
        BitmapFactory.decodeFile(imgPath, options); // 解码文件
        if (options.outWidth == -1 || options.outHeight == -1) {
            int[] wh = getPicRealWidthHeight(imgPath);
            options.outWidth = wh[0];
            options.outHeight = wh[1];
        }
        // 计算缩放值
        options.inSampleSize = calculateInSampleSize(options, reqWidth,
                reqHeight);
        // 设置好缩放值之后，inJustDecodeBounds设为false，就可以根据已经得到的缩放比例得到自己想要的图片缩放图
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        options.inJustDecodeBounds = false;
        int degree = getPicRotateDegree(imgPath);
        Bitmap bitmap;
        if (degree != 0) {
            bitmap = rotateBitmap(BitmapFactory.decodeFile(imgPath, options), degree);
        } else {
            bitmap = BitmapFactory.decodeFile(imgPath, options);
        }
        return bitmap;
    }

    /**
     * 根据图片源Id获取压缩后的Bitmap
     *
     * @param imgId     图片路径ID
     * @param reqWidth  期望压缩宽度
     * @param reqHeight 期望压缩高度
     * @return Bitmap对象
     */
    public static Bitmap getSmallBitmap(Context context, int imgId, int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;// 如果该值设为true那么将不返回实际的bitmap对象，不给其分配内存空间但是可以得到一些解码边界信息即图片大小等信息
        BitmapFactory.decodeResource(context.getResources(), imgId, options); // 解码文件
        // 计算缩放值
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        // 设置好缩放值之后，inJustDecodeBounds设为false，就可以根据已经得到的缩放比例得到自己想要的图片缩放图
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        options.inJustDecodeBounds = false;
        InputStream is = context.getResources().openRawResource(imgId);
        Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    /**
     * 计算图片的缩放值
     *
     * @param options
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // 获取图片的原始高度和宽度
        final int width = options.outWidth;
        final int height = options.outHeight;
        int inSampleSize = 1; // inSampleSize为1表示宽度和高度不缩放

        if (width > reqWidth || height > reqHeight) {
            // 如果原始宽高都比期望压缩后的图片宽高大则计算宽高缩放比例，否则不进行压缩
            final int widthRadio = Math.round((float) width / (float) reqWidth);
            final int heightRadio = Math.round((float) height
                    / (float) reqHeight);
            inSampleSize = Math.max(widthRadio, heightRadio);
        }
        return inSampleSize; // 返回缩放值
    }

    /**
     * 获取图片旋转角度
     *
     * @param picFilePath 图片路径[绝对路径]
     * @return 图片旋转角度
     */
    public static int getPicRotateDegree(String picFilePath) {
        int degree = 0;
        try {
            ExifInterface exif = new ExifInterface(picFilePath);
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return degree;
    }


    private static Bitmap rotateBitmap(Bitmap bitmap, int degree) {
        //使用矩阵旋转图片
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        //旋转图片
        Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),
                matrix, true);
        //回收掉旋转前的图片
        if (!bitmap.isRecycled()) {
            bitmap.recycle();
        }
        return rotatedBitmap;
    }


    /**
     * 获取图片真实宽高
     *
     * @param picFilePath 图片文件路径[绝对路径]
     * @return [宽, 高]
     */
    public static int[] getPicRealWidthHeight(String picFilePath) {
        int[] wh = new int[2];
        try {
            ExifInterface exif = new ExifInterface(picFilePath);
            wh[0] = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, -1);
            wh[1] = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, -1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return wh;
    }

    /**
     * 压缩bitmap对象
     *
     * @param bitmap
     * @param kb     要压缩的大小
     * @return
     */
    public static Bitmap compressImage(Bitmap bitmap, int kb) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(CompressFormat.JPEG, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int options = 100;//压缩质量
        while (baos.toByteArray().length / 1024 > kb) { // 循环判断如果压缩后图片是否大于kb,大于继续压缩
            baos.reset();// 重置baos即清空baos
            bitmap.compress(CompressFormat.JPEG, options, baos);// 这里压缩options%，把压缩后的数据存放到baos中
            options -= 10;// 每次都减少10
            if (options <= COMPRESS_QUALITY) {
                //最多压缩20%，不然图片会很模糊
                break;
            }
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        return bitmap;
    }
}
